﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Admin.NET.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Microsoft.AspNetCore.Http;
using System.Text;
using System.Web;
using System.ComponentModel;
using System.Data;
namespace Admin.NET.Application
{
    /// <summary>
    /// 学生视图服务
    /// </summary>
    [ApiDescriptionSettings("TestDemo", Name = "VStudent", Order = 100)]
    [Route("api/[Controller]")]
    public class VStudentService : IVStudentService, IDynamicApiController, ITransient
    {
        private readonly IRepository<VStudent,MasterDbContextLocator> _vStudentRep;
        private readonly IRepository<SysDictType, MasterDbContextLocator> _sysDictTypeRep;
        private readonly IRepository<SysDictData, MasterDbContextLocator> _sysDictDataRep;
        private readonly ISysExcelTemplateService _sysExcelTemplateService;
        private readonly static object _lock = new();

        public VStudentService(
            IRepository<VStudent,MasterDbContextLocator> vStudentRep
            ,IRepository<SysDictType, MasterDbContextLocator> sysDictTypeRep
            ,IRepository<SysDictData, MasterDbContextLocator> sysDictDataRep
            ,ISysExcelTemplateService sysExcelTemplateService
        )
        {
            _vStudentRep = vStudentRep;
         _sysDictTypeRep = sysDictTypeRep;
         _sysDictDataRep = sysDictDataRep;
         _sysExcelTemplateService = sysExcelTemplateService;
        }

        /// <summary>
        /// 分页查询学生视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/page")]
        [HttpGet("page")]
        public async Task<PageResult<VStudentOutput>> Page([FromQuery] VStudentSearch input)
        {
            var vStudents = await _vStudentRep.DetachedEntities
                                     .Where(input.Id != null, u => u.Id == input.Id)
                                     .Where(!string.IsNullOrEmpty(input.Name), u => u.Name == input.Name)
                                     .Where(input.Age != null, u => u.Age == input.Age)
                                     .Where(input.StartName != null, u => u.StartName == input.StartName)
                                     .Where(input.Gender != null, u => u.Gender == input.Gender)
                                     .Where(input.BrithDate != null, u => u.BrithDate == input.BrithDate)
                                     .Where(input.TeacherId != null, u => u.TeacherId == input.TeacherId)
                                     .Where(!string.IsNullOrEmpty(input.teacherName), u => u.teacherName == input.teacherName)
                                     .OrderBy(PageInputOrder.OrderBuilder<VStudentSearch>(input))
                                     .ProjectToType<VStudentOutput>()
                                     .ToADPagedListAsync(input.PageNo, input.PageSize);
            return vStudents;
        }

        /// <summary>
        /// 不分页查询学生视图列表
        /// </summary>
        /// <param name="input">学生视图查询参数</param>
        /// <returns>(学生视图)实例列表</returns>
        [Description("VStudent/listNonPage")]
        [HttpGet("listNonPage")]
        public async Task<List<VStudentOutput>> ListNonPageAsync([FromQuery] VStudentSearchNonPage input)
        {
            var pId = input.Id;
            var pName = input.Name?.Trim() ?? "";
            var pAge = input.Age;
            var pStartName = input.StartName;
            var pGender = input.Gender;
            var pBrithDate = input.BrithDate;
            var pTeacherId = input.TeacherId;
            var pteacherName = input.teacherName?.Trim() ?? "";
            var vStudents = await _vStudentRep.DetachedEntities
                .Where(pId != null, u => u.Id == pId)
                .Where(!string.IsNullOrEmpty(pName), u => u.Name == pName)
                .Where(pAge != null, u => u.Age == pAge)
                .Where(pStartName != null, u => u.StartName == pStartName)
                .Where(pGender != null, u => u.Gender == pGender)
                .Where(pBrithDate != null, u => u.BrithDate == pBrithDate)
                .Where(pTeacherId != null, u => u.TeacherId == pTeacherId)
                .Where(!string.IsNullOrEmpty(pteacherName), u => u.teacherName == pteacherName)
            .OrderBy(PageInputOrder.OrderNonPageBuilder(input))
            .ProjectToType<VStudentOutput>()
            .ToListAsync();
            return vStudents;
        }


        /// <summary>
        /// 增加学生视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/add")]
        [HttpPost("add")]
        public async Task Add(AddVStudentInput input)
        {
            var vStudent = input.Adapt<VStudent>();
                        //验证
            await CheckExisit(vStudent);

            vStudent.CreatedUserId = vStudent.UpdatedUserId = SysHelper.GetUserId();
            vStudent.CreatedUserName = vStudent.UpdatedUserName = SysHelper.GetUserName();
            vStudent.CreatedTime = vStudent.UpdatedTime = SysHelper.GetNowTime();
            await _vStudentRep.InsertAsync(vStudent);
        }

        /// <summary>
        /// 删除学生视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/delete")]
        [HttpPost("delete")]
        public async Task Delete(DeleteVStudentInput input)
        {
            
        }

        /// <summary>
        /// 更新学生视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/edit")]
        [HttpPost("edit")]
        public async Task Update(UpdateVStudentInput input)
        {
            var isExist = await _vStudentRep.AnyAsync(u => u.Id == input.Id, false);
            if (!isExist) throw Oops.Oh(ErrorCode.D1002);

            var vStudent = input.Adapt<VStudent>();
            //验证
            await CheckExisit(vStudent,true);

            vStudent.UpdatedUserId = SysHelper.GetUserId();
            vStudent.UpdatedUserName = SysHelper.GetUserName();
            vStudent.UpdatedTime = SysHelper.GetNowTime();
            await _vStudentRep.UpdateAsync(vStudent,ignoreNullValues:true);
        }

        /// <summary>
        /// 获取学生视图
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/detail")]
        [HttpGet("detail")]
        public async Task<VStudentOutput> Get([FromQuery] QueryeVStudentInput input)
        {
            return null;
            return null;
            return null;
            return null;
            return null;
            return null;
            return null;
            return null;
        }

        /// <summary>
        /// 获取学生视图列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Description("VStudent/list")]
        [HttpGet("list")]
        public async Task<List<VStudentOutput>> List([FromQuery] VStudentInput input)
        {
            return await _vStudentRep.DetachedEntities.ProjectToType<VStudentOutput>().ToListAsync();
        }    
         /// <summary>
        /// Excel模板导入学生视图功能
        /// </summary>
        /// <param name="file">Excel模板文件</param>
        /// <param name="importExcelType">Excel导入方式</param>
        /// <returns>导入的记录数</returns>
        [HttpPost("fromExcel")]
        public async Task<int> FromExcelAsync(IFormFile file, [FromQuery] ImportExcelType importExcelType)
        { 
            int _HeadStartLine = 2;//第1行是说明,第2行是列名
            int _DataStartLine = 3;//第3行开始是数据

            DataTable importDataTable = ExcelUtil.ImportExcelToDataTable(file, _HeadStartLine, _DataStartLine);
            var addList =await CommonImport(importDataTable, _DataStartLine);

            lock (_lock)
            {
                _vStudentRep.InsertAsync(addList);
               
            }
            await Task.CompletedTask;
            return addList.Count;
        }

        /// <summary>
        ///  DataTable转换实体对象列表
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="dataStartLine">模版列名开始行</param>
        /// <returns></returns>
          private async Task<List<VStudent>> CommonImport(DataTable dataTable, int dataStartLine)
        {

            var details = new List<VStudent>();
            int index = dataStartLine;//模版列名开始行
            foreach (System.Data.DataRow row in dataTable.Rows)
            {
                index++;

               //导入模版定制化代码（替换模版使用）
                                          
                           var addItem = new VStudent()
                            {
                               CreatedTime = SysHelper.GetNowTime(),
                               CreatedUserId = SysHelper.GetUserId(),
                               CreatedUserName = SysHelper.GetUserName(),
                               UpdatedTime = SysHelper.GetNowTime(),
                               UpdatedUserId = SysHelper.GetUserId(),
                               UpdatedUserName = SysHelper.GetUserName()
                             };
                          #region 定义变量
                           var _Id = "";//Id主键
                           var _Name = "";//学生姓名
                           var _Age = "";//学生年龄
                           var _StartName = "";//是否在校
                           var _Gender = "";//性别
                           var _BrithDate = "";//出生日期
                           var _TeacherId = "";//关联老师
                           var _teacherName = "";//老师名称
                          #endregion
                          
                          
                          #region 取值
                           _Id = row["Id主键"]?.ToString() ;
                           _Name = row["学生姓名"]?.ToString() ;
                           _Age = row["学生年龄"]?.ToString() ;
                           _StartName = row["是否在校"]?.ToString() ;
                           _Gender = row["性别"]?.ToString() ;
                           _BrithDate = row["出生日期"]?.ToString() ;
                           _TeacherId = row["关联老师"]?.ToString() ;
                           _teacherName = row["老师名称"]?.ToString() ;
                          #endregion
                          
                          
                          #region 验证
                          if(!string.IsNullOrEmpty(_Id))
                          {
                              if (!long.TryParse(_Id, out long outId)&&!string.IsNullOrEmpty(_Id))
                              {
                                 throw Oops.Oh($"第{index}行[Id主键]{_Id}值不正确！");
                              }
                              if (outId <= 0&&!string.IsNullOrEmpty(_Id))
                              {
                                 throw Oops.Oh($"第{index}行[Id主键]{_Id}值不能小于等于0！");
                              }
                              else
                              {
                                 addItem.Id = outId;
                              }
                          
                          }
                          if(!string.IsNullOrEmpty(_Name))
                          {
                                addItem.Name = (string)_Name;
                           }
                          if(!string.IsNullOrEmpty(_Age))
                          {
                              if (!int.TryParse(_Age, out int outAge)&&!string.IsNullOrEmpty(_Age))
                              {
                                 throw Oops.Oh($"第{index}行[学生年龄]{_Age}值不正确！");
                              }
                              if (outAge <= 0&&!string.IsNullOrEmpty(_Age))
                              {
                                 throw Oops.Oh($"第{index}行[学生年龄]{_Age}值不能小于等于0！");
                              }
                              else
                              {
                                 addItem.Age = outAge;
                              }
                          
                          }
                          if(!string.IsNullOrEmpty(_StartName))
                          {
                            if(!_StartName.Equals("是") && !_StartName.Equals("否"))
                             {
                               throw Oops.Oh($"第{index}行[是否在校]{_StartName}值不正确！");
                             }
                             else
                             {
                               bool outStartName = _StartName.Equals("是") ? true : false;
                               addItem.StartName = outStartName;
                             }
                             }
                          
                          if(!string.IsNullOrEmpty(_Gender))
                          {
                          System.Int32  enumGender = default(System.Int32);
                          
                             if(!Enum.TryParse<System.Int32>(_Gender, out enumGender)&&!string.IsNullOrEmpty(_Gender))
                              {
                                throw Oops.Oh($"第{index}行[性别]{_Gender}值不正确！");
                              }
                              else
                              {
                                 addItem.Gender = enumGender;
                              }
                          
                           }
                          if(!string.IsNullOrEmpty(_BrithDate))
                          {
                                addItem.BrithDate = Convert.ToDateTime(Convert.ToDateTime(_BrithDate).ToShortDateString());
                           }
                          if(!string.IsNullOrEmpty(_TeacherId))
                          {
                              if (!long.TryParse(_TeacherId, out long outTeacherId)&&!string.IsNullOrEmpty(_TeacherId))
                              {
                                 throw Oops.Oh($"第{index}行[关联老师]{_TeacherId}值不正确！");
                              }
                              if (outTeacherId <= 0&&!string.IsNullOrEmpty(_TeacherId))
                              {
                                 throw Oops.Oh($"第{index}行[关联老师]{_TeacherId}值不能小于等于0！");
                              }
                              else
                              {
                                 addItem.TeacherId = outTeacherId;
                              }
                          
                          }
                          if(!string.IsNullOrEmpty(_teacherName))
                          {
                                addItem.teacherName = (string)_teacherName;
                           }
                          #endregion
                          

                //验重
                await CheckExisit(details, addItem,index);
                details.Add(addItem);
            }

            return details;
        }

        /// <summary>
        /// 根据版本下载学生视图的Excel导入模板
        /// </summary>
        /// <param name="version">模板版本</param>
        /// <returns>下载的模板文件</returns>
        [Description("VStudent/downloadExcelTemplate")]
        [HttpGet("downloadExcelTemplate")]
        public IActionResult DownloadExcelTemplate([FromQuery] string version)
        {
            string _path = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + $"\\VStudent{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx";
            var fileName = HttpUtility.UrlEncode($"导入模板(学生视图).xlsx", Encoding.GetEncoding("UTF-8"));
            return new FileStreamResult(new FileStream(_path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
        }

        /// <summary>
        /// 根据学生视图查询参数导出Excel
        /// </summary>
        /// <param name="input">学生视图查询参数</param>
        /// <returns>导出的Excel文件</returns>
        [Description("VStudent/toExcel")]
        [HttpGet("toExcel")]
        public async Task<IActionResult> ToExcelAsync([FromQuery] VStudentSearchNonPage input)
        {
            var vStudentList = await ListNonPageAsync(input);
            MemoryStream ms = new();
            DataConvertUtil.ToExcelData(vStudentList, _sysDictTypeRep, _sysDictDataRep, out List<string> headers, 
                out List<List<object>> data, out string sheetName);
            var excelTemplate = await _sysExcelTemplateService.GetByAppNameAndClassNameAndVersionAsync("VStudent", "v1");
            if (excelTemplate != null)
            {
                ExcelUtil.ToExcel(excelTemplate.TemplateFileName, headers, data, sheetName, excelTemplate.HeadStartLine, excelTemplate.DataStartLine, ms);
            }
            else 
            {
                ExcelUtil.ToExcel(headers, data, sheetName, ms);
            }
            ms.Position = 0;
            var fileName = HttpUtility.UrlEncode($"{sheetName}[{DateTimeOffset.Now:yyyy-MM-dd}].xlsx", Encoding.GetEncoding("UTF-8"));
            return new FileStreamResult(ms, "application/octet-stream") { FileDownloadName = fileName };
        }



        
        



        /// <summary>
        /// 根据联合主键验证数据是否已存在-数据库
        /// </summary>
        /// <param name="input"></param>
        /// <param name="isEdit"></param>
        /// <param name="index">导入模板excel行号</param>
        /// <returns></returns>
        private async Task CheckExisit( VStudent input,bool isEdit=false,int index=0)
        {
           

           

          
                
               
        

            //没有配置联合主键，不需要验重

             
           
              

        }

        /// <summary>
        /// 根据联合主键验证数据是否已存在-导入的数据集
        /// </summary>
        /// <param name="inputs"></param>
        /// <param name="input"></param>
        /// <param name="index">导入模板excel行号</param>
        private async Task CheckExisit(List<VStudent> inputs,VStudent input, int index)
        {

                //没有配置联合主键，不需要验重
            
           
        }


    }
}
